package com.iuv.shortmsg.controller;

import com.aliyuncs.dysmsapi.model.v20170525.SendSmsResponse;
import com.google.gson.Gson;
import com.iuv.shortmsg.common.CommonOperateCode;
import com.iuv.shortmsg.domain.DemoSmsUserTbl;
import com.iuv.shortmsg.dto.SmsCodeInfo;
import com.iuv.shortmsg.service.DemoSmsUserService;
import com.iuv.shortmsg.util.IuvDateUtil;
import com.iuv.shortmsg.util.RandomCodeUtil;
import com.iuv.shortmsg.util.RespondUtil;
import com.iuv.shortmsg.util.SmsUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * RegistController
 * 注册控制器
 *
 * @author Will
 * @date 16:33
 */
@Controller
@RequestMapping("regist")
public class RegistController {
    private static Logger logger = LoggerFactory.getLogger(RegistController.class);
    /**
     * 验证码缓存，应用于生产项目时可用redis重构
     */
    private static ConcurrentHashMap<String, SmsCodeInfo> SMS_CODE_MAP = new ConcurrentHashMap<String, SmsCodeInfo>();

    /**
     * 签名模板
     */
    private static final String SIGN_NAME = "深圳市艾优威科技";
    /**
     * 注册短信验证码模板
     */
    private static String REGIST_TEMPLATE_CODE = "SMS_126270369";
    /**
     * 验证码的有效时间（单位为分钟）
     */
    private static long CODE_VALID_MINUTE = 15L;
    /**
     * 引入用户业务接口
     */
    @Autowired
    private DemoSmsUserService demoSmsUserService;

    /**
     * 获取短信验证码
     *
     * @param mobile
     * @return
     */
    @RequestMapping("getSmsCode")
    @ResponseBody
    public Map<String, Object> querySmsCode(@RequestParam String mobile) {

        mobile = StringUtils.trimToNull(mobile);

        /**
         * TODO 短信注册 问题一 [if 关键字的基础使用]
         *
         *   通过if条件判断 mobile是否为空
         */
        if (mobile == null) {
            logger.info("用户输入的号码为空");
        }
        /**
         * end
         */

        /**
         * TODO 短信注册 问题二 [if else 多层嵌套使用，]
         * if else if 多层嵌套使用 ，判断长度是否大于 11
         * 否则判断长度是否小于11位
         * 否则 正确
         *
         */
        if (mobile.length()>11) {
            logger.info("用户输入的手机号大于11位");
        }else if (mobile.length()<11) {
            logger.info("用户输入的手机号小于11位");
        }else {
            logger.info("用户输入的手机号正确");
        }
        /**
         * end
         */


        if (mobile == null) {
            return RespondUtil.respondFail(CommonOperateCode.SysCode.REGIST_MOBILE_NOT_NULL,
                    CommonOperateCode.SysMsg.REGIST_MOBILE_NOT_NULL);
        }

        if (demoSmsUserService.checkMobileExist(mobile)) {
            return RespondUtil.respondFail(CommonOperateCode.SysCode.REGIST_MOBILE_HAVE_EXIST,
                    CommonOperateCode.SysMsg.REGIST_MOBILE_HAVE_EXIST);
        }

        Gson gson = new Gson();

        Map<String, Object> templateParamMap = new HashMap<>();

        String code = RandomCodeUtil.genMsgRandomCode();

        /**
         * TODO 短信注册 问题三 [三元表达式的使用]
         * 判断code是否为空，，为空 则通过 RandomCodeUtil.genMsgRandomCode() 重新获取，不为空则重新赋值
         *
         *
         */
        code = (code == null ? RandomCodeUtil.genMsgRandomCode() : code);

        /**
         * end
         */

        templateParamMap.put("code", code);


        String templateParam = gson.toJson(templateParamMap);

        //发送信息验证码
        SendSmsResponse sendSmsResponse = SmsUtil.sendSms(mobile, SIGN_NAME, REGIST_TEMPLATE_CODE, templateParam);

        if (sendSmsResponse == null || !"OK".equalsIgnoreCase(sendSmsResponse.getCode())) {
            return RespondUtil.respondFail(CommonOperateCode.SysCode.SMS_SEND_ERROR,
                    CommonOperateCode.SysMsg.SMS_SEND_ERROR);
        }
        //缓存已发送的验证码，供下一请求验证使用
        SmsCodeInfo smsCodeInfo = new SmsCodeInfo(mobile, code);
        SMS_CODE_MAP.put(mobile, smsCodeInfo);
        logger.info("短信验证码为：" + code);
        return RespondUtil.respondSuccess("", "");
    }

    /**
     * 用户注册
     *
     * @param mobile
     * @param code
     * @param password
     * @param comfirmPassword
     * @return
     */
    @RequestMapping("regist")
    @ResponseBody
    public Map<String, Object> regist(@RequestParam String mobile, @RequestParam String code, @RequestParam String password, @RequestParam String comfirmPassword) {
        if (mobile == null) {
            return RespondUtil.respondFail(CommonOperateCode.SysCode.REGIST_MOBILE_NOT_NULL, CommonOperateCode.SysMsg.REGIST_MOBILE_NOT_NULL);
        }
        /**
         * TODO 短信注册 问题四 [多种条件判断的if]
         * 多种不同的判断条件，通过与或非符号进行连接 || 或者&&
         * 判断条件  password 不为空 或  comfirmPassword不为空  或 password 不和 comfirmPassword一致
         *
         */
        if (password == null || comfirmPassword == null || !password.equals(comfirmPassword)) {
            return RespondUtil.respondFail(
                    CommonOperateCode.SysCode.REGIST_PASSWORD_NOT_CORRECT,
                    CommonOperateCode.SysMsg.REGIST_PASSWORD_NOT_CORRECT);
        }

        /**
         * end
         */


        if (code == null || !SMS_CODE_MAP.containsKey(mobile)) {
            return RespondUtil.respondFail(CommonOperateCode.SysCode.REGIST_CODE_NOT_EXIST,
                    CommonOperateCode.SysMsg.REGIST_CODE_NOT_EXIST);
        }
        SmsCodeInfo smsCodeInfo = SMS_CODE_MAP.get(mobile);
        //检查验证码的有效性（15分钟内有效）
        if (!(smsCodeInfo.getCode().equalsIgnoreCase(code) && IuvDateUtil.isBeforeDate(smsCodeInfo.getCreateTime().plusMinutes(CODE_VALID_MINUTE)))) {
            return RespondUtil.respondFail(CommonOperateCode.SysCode.REGIST_CODE_INAVALID, CommonOperateCode.SysMsg.REGIST_CODE_INAVALID);
        }
        //删除缓存
        SMS_CODE_MAP.remove(mobile);
        //创建帐户
        DemoSmsUserTbl user = demoSmsUserService.createUser(mobile, password);
        /**
         * TODO 短信注册 问题五 [switch 条件判断]
         * 判断是第几个用户 第一个输出 第一个用户
         * 第N个输出第N个用户
         */
        switch (user.getUserId()) {
            case 1:
                logger.info("第一个用户");
                break;
            default:
                logger.info("第{}个用户", user.getUserId());
                break;
        }
        if (user != null) {
            logger.info("第"+user.getUserId()+"个用户");
        }
        /**
         * end
         */

        return RespondUtil.respondSuccess(CommonOperateCode.SysCode.REGIST_SUCCESS, CommonOperateCode.SysMsg.REGIST_SUCCESS);
    }
}
